package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class InvocationHandlerTest1 implements InvocationHandler {

    private A a;

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(!method.getName().contains("fun")) {
            return method.invoke(proxy, args);
        }
        System.out.println("before");
        Object invoke = method.invoke(a, args);
        System.out.println("after");
        return invoke;
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), a.getClass().getInterfaces(), this);
    }

    public static void main(String[] args) {
        InvocationHandlerTest1 ih1 = new InvocationHandlerTest1();
        A aimpl = new AImpl();
        ih1.setA(aimpl);

        A proxy = (A) ih1.getProxy();
        proxy.fun1();

    }

    interface A {
        void fun1();

        void fun2();
    }

    static class AImpl implements A {

        @Override
        public void fun1() {
            System.out.println("f1");
        }

        @Override
        public void fun2() {
            fun1();
        }
    }
}
